home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1995 May / cd Ware (Juegos) Epimundo.iso / DOS / C / RANDIO.ZIP / RANDIO.C < prev   
Encoding:
C/C++ Source or Header  |  1993-07-14  |  6.0 KB  |  253 lines

  1.  
  2.  
  3. /*
  4.  * RANDIO.C by Ed Mulroy
  5.  *
  6.  * Simple demo of random access in files
  7.  *
  8.  * A file with 10 records is created
  9.  *
  10.  * Each record consists of the number of the record repeated 13 times
  11.  * followed by a <cr><lf> so that it could be viewed with a text editor
  12.  *
  13.  * The user can select record number to display, or can ask to see them all
  14.  *
  15.  * Illustrations of how to do certain things:
  16.  *
  17.  *   Random access by record number -
  18.  *     read_record()
  19.  *     display_all_records()
  20.  *
  21.  *   Getting the file size and number of records in a FILE * type file:
  22.  *     num_records_in_file()
  23.  *
  24.  *   Getting a key from the keyboard, including function key values
  25.  *     get_key()
  26.  *     #define macro F()
  27.  *
  28.  * While written as C code, this should work as C or C++ in any memory model
  29.  *
  30.  */
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>  /* for prototype of memset() */
  35. #include <conio.h>   /* for prototype of getch()  */
  36.  
  37.  
  38. #define RECORD_SIZE 15       /* number of bytes in one record */
  39. #define ESCAPE      '\x1B'   /* escape key value */
  40.  
  41. #define F(N)  ((0x3A + N) << 8)
  42.  
  43.  
  44. unsigned num_records;
  45. FILE    *fptr;
  46.  
  47. char *filename = "DEMO.DAT";
  48. char *prompt =
  49.   "\nEnter record number [0-9] 'A' for all or press <Esc> to end  ";
  50.  
  51. char *helpstring =
  52.   "\n"
  53.   "\n"
  54.   "\tRANDIO.C by Ed Mulroy\n"
  55.   "\n"
  56.   "\tSimple demo of random access in files\n"
  57.   "\n"
  58.   "\tA file with 10 records is created.  Each record consists of\n"
  59.   "\tthe number of the record repeated 13 times followed by a\n"
  60.   "\t<cr><lf> so that it can be viewed with a text editor.  The\n"
  61.   "\tuser can select record number to display, or can ask to see\n"
  62.   "\tthem all\n";
  63.  
  64.  
  65.  
  66. /* display system error message and quit with an error exit code */
  67. void fatal(void)
  68.   {
  69.   perror("");
  70.   exit(EXIT_FAILURE);
  71.   }
  72.  
  73.  
  74.  
  75.  
  76. /*
  77.  * Read normal keys as you would expect and special keys as a
  78.  * value with 0 as the low byte and a number in the high byte
  79.  *
  80.  * The special key values are the same as would be returned if
  81.  * the BIOS were called.
  82.  *
  83.  * Does not detect an enhanced keyboard nor respond to its extra
  84.  * special keys such as F11 and F12
  85.  */
  86. int get_key(void)
  87.   {
  88.   int i;
  89.  
  90.   i = getch();         /* get normal keys as the expected value */
  91.  
  92.   if (!i)              /* if function or special key, get it also */
  93.     i = getch() << 8;
  94.  
  95.   return i;
  96.   }
  97.  
  98.  
  99.  
  100.  
  101. int create_file(void)
  102.   {
  103.   char buffer[RECORD_SIZE]; /* array of char's, not a string */
  104.   char c;
  105.  
  106.   fptr = fopen(filename, "w+b"); /* note the binary mode open */
  107.  
  108.   if (fptr == NULL)
  109.     return 0;
  110.  
  111.   buffer[RECORD_SIZE - 2] = '\r'; /* make record buffer end in a newline */
  112.   buffer[RECORD_SIZE - 1] = '\n'; /* so a text editor can look at it     */
  113.  
  114.   for (c = '0'; c <= '9'; c++)
  115.     {
  116.     memset(buffer, c, RECORD_SIZE - 2);
  117.     fwrite(buffer, sizeof(buffer), 1, fptr);
  118.  
  119.     if (ferror(fptr))
  120.       return 0;
  121.     }
  122.  
  123.   return 1;
  124.   }
  125.  
  126.  
  127.  
  128.  
  129. int read_record(FILE *f, void *buffer, unsigned rec_num, unsigned rec_size)
  130.   {
  131.   /* position in file, fseek() returns 0 on success */
  132.   if (fseek(f, rec_num * (long) rec_size, SEEK_SET) == 0)
  133.     {
  134.     if (fread(buffer, rec_size, 1, f) == 1) /* read the record */
  135.       return 1;
  136.     }
  137.  
  138.   return 0;
  139.   }
  140.  
  141.  
  142.  
  143.  
  144. void display_all_records(void)
  145.   {
  146.   unsigned rec_num;
  147.   char     buffer[RECORD_SIZE];
  148.  
  149.   printf("\nFile has %d records\n"
  150.           "Displaying them in reverse order\n", num_records);
  151.  
  152.   if (num_records < 1)
  153.     return;
  154.  
  155.   /* illustrate seeking in the file by reading and showing */
  156.   /* odd records and then even ones in descending order    */
  157.   for (rec_num = (num_records - 1) | 1; rec_num != 0xFFFEU; rec_num -= 2)
  158.     {
  159.     if (rec_num == 0xFFFFU)             /* if done with odd records    */
  160.       rec_num = (num_records - 1) & ~1; /* start with highest even one */
  161.  
  162.     fseek(fptr, rec_num * RECORD_SIZE, SEEK_SET);
  163.     fread(buffer, RECORD_SIZE, 1, fptr);
  164.     printf("%3u: ", rec_num);
  165.     fwrite(buffer, RECORD_SIZE, 1, stdout);
  166.     }
  167.  
  168.   putchar('\n');
  169.   }
  170.  
  171.  
  172.  
  173.  
  174. int num_records_in_file(FILE *fileptr, unsigned record_size)
  175.   {
  176.   long pos_b4;
  177.   long file_size;
  178.  
  179.   if (record_size == 0)             /* trap possible divide by 0 error */
  180.     return 0;
  181.  
  182.   pos_b4 = ftell(fileptr);          /* save current position */
  183.   fseek(fileptr, 0, SEEK_END);      /* go to end of file */
  184.   file_size = ftell(fileptr);       /* get position as the file size */
  185.   fseek(fileptr, pos_b4, SEEK_SET); /* restore old position */
  186.   return (unsigned) (file_size / record_size);
  187.   }
  188.  
  189.  
  190.  
  191.  
  192. int main()
  193.   {
  194.   int      keyin;
  195.   unsigned record_num;
  196.   char     buffer[RECORD_SIZE];
  197.  
  198.   puts("RANDIO random file I/O demo - press F1 at any time for help\n");
  199.  
  200.   if (!create_file())
  201.     fatal();
  202.  
  203.   num_records = num_records_in_file(fptr, RECORD_SIZE);
  204.  
  205.   do
  206.     {
  207.     fputs(prompt, stdout);
  208.  
  209.     do         /* loop until valid input received */
  210.       {
  211.       putchar('\b');    /* back up to position where key will be shown */
  212.       keyin = get_key();
  213.  
  214.       if (keyin == F(1))
  215.         {
  216.         puts(helpstring);
  217.         fputs(prompt, stdout); /* fputs() doesn't add a newline at end */
  218.         }
  219.       else if (keyin == 'a')
  220.         keyin = 'A';
  221.  
  222.       if ((keyin >= ' ') && (keyin <= '~'))
  223.         putchar(keyin);           /* if a printable key show it */
  224.       else
  225.         putchar('?');             /* show '?' for non-printable key */
  226.  
  227.       } while ((keyin != ESCAPE) && (keyin != 'A') &&
  228.                !((keyin >= '0') && (keyin <= '9')));
  229.  
  230.     if ((keyin >= '0') && (keyin <= '9'))
  231.      {
  232.      record_num = keyin - '0';
  233.      putchar('\n');
  234.  
  235.      if (!read_record(fptr, buffer, record_num, RECORD_SIZE))
  236.        fatal();
  237.  
  238.      printf("\nRecord #%3u: ", record_num);
  239.      fwrite(buffer, RECORD_SIZE, 1, stdout);
  240.      putchar('\n');
  241.      }
  242.     else if (keyin == 'A')
  243.       display_all_records();
  244.  
  245.     } while (keyin != ESCAPE);
  246.  
  247.   fclose(fptr);
  248.   putchar('\n');
  249.   return EXIT_SUCCESS;
  250.   }
  251.  
  252.  
  253.